package cn.com.winning.hic;

import org.dom4j.*;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.util.List;

public class DomUtils {

     public static final  String nodeTagName = "node";
     public static final  String refTagName = "Ref";

     private static final String valueAttrName = "value";
     private static final String textAttrName = "text";
     private static final String refidAttrName = "refid";
     private static final String nodetypeAttrName = "nodetype";
     private static final String idAttrName = "id";


     public static final  String dtjdNodeType = "DynamicMoleNode";
     public static final  String textNodeType = "Text";
     public static final  String refNodeType = "Embeded";
     public static final  String objectNodeType = "Object";
     public static final  String atomNodeType = "AtomNode";

     public static void main(String[] args){
          InputStream in = DomUtils.class.getClassLoader().getResourceAsStream("24hcryjl.xml");
          System.out.println(in);
          SAXReader reader = new SAXReader();
          Document document = null;
          try {
               document = reader.read(in);
          } catch (DocumentException e) {
               e.printStackTrace();
          }

          Element rootElement = document.getRootElement();
          TemplateInfo info = new TemplateInfo();
          info.setDtjddm("2079e311-fddc-488e-955a-e5dc61e18c35");
          info.setQrmbdm(null);
          info.setQrdxdm(null);
          info.setYzjddm(null);
          System.out.println(resolveNodeInfo(rootElement,info));
     }

     public static String resolveNodeInfo( Element rootElement, TemplateInfo info){
          //获取所有的node子节点
          List<Element> nodeChildList = rootElement.elements(nodeTagName);
          //定义需要的node子节点
          Element dynamicModelNode = null;
          //遍历所有的子节点,找到需要文件结构节点
          for (Element childEle : nodeChildList) {
               Attribute idAttr = childEle.attribute(idAttrName);
               if(idAttr != null && info.getDtjddm().equals(idAttr.getValue())){
                    dynamicModelNode = childEle;
                    break;
               }
          }
          StringBuilder builder = new StringBuilder();
          //遍历文件结构的子节点
          List<Element> dynamicChildNodeList = dynamicModelNode.elements(nodeTagName);

          for (Element element : dynamicChildNodeList) {
               Attribute nodeTypeAttr = element.attribute(nodetypeAttrName);
               if(info.getQrmbdm() == null){
                    if(nodeTypeAttr != null && textNodeType.equals(nodeTypeAttr.getValue())){ //文本节点
                         builder.append(element.attribute(textAttrName).getValue());
                    }else if(nodeTypeAttr != null && refNodeType.equals(nodeTypeAttr.getValue())){ //引入节点
                         builder.append(resolveRefNode(rootElement,element.attribute(refidAttrName).getValue(),info));
                    }
               }else{
                    if(nodeTypeAttr != null && refNodeType.equals(nodeTypeAttr.getValue())){ //引入节点
                         builder.append(resolveRefNode(rootElement,element.attribute(refidAttrName).getValue(),info));
                    }
               }

          }
          System.out.println(builder.toString());
          return builder.toString();
     }
     /**
      * 解析Ref引用节点
      * @param rootElement
      * @param refId
      * @return
      */
     private static String resolveRefNode(Element rootElement, String refId,TemplateInfo info) {
          StringBuilder builder = new StringBuilder();
          //获取所有的Ref元素
          List<Element> refList = rootElement.elements(refTagName);
          Element refElement = null;
          //提取指定基础模板元素
          for (Element element : refList) {
               Attribute idAttr = element.attribute(idAttrName);
               if(idAttr != null && refId.equals(idAttr.getValue())){
                    refElement = element;
               }
          }
          //获取基础模板元素
          Element refChildElement = refElement.element(nodeTagName);
          //获取基础模板元素子节点集合
          List<Element> embededElementList  = refChildElement.elements(nodeTagName);
          //遍历解析基础模板子节点
          for (Element element : embededElementList) {
               //获取节点类型属性
               Attribute nodeTypeAttr = element.attribute(nodetypeAttrName);
               //获取节点ID属性
               Attribute idAttr = element.attribute(idAttrName);
               //只有文件结构ID，没有模板ID，取全部数据
               if(info.getQrmbdm() == null){
                    if(nodeTypeAttr != null && textNodeType.equals(nodeTypeAttr.getValue())){
                         builder.append(
                                 element.attribute(textAttrName)== null ? "" :element.attribute(textAttrName).getValue());
                    }else if(nodeTypeAttr != null && objectNodeType.equals(nodeTypeAttr.getValue())){
                         builder.append(resolveObjectNode(element,info));
                    }
               }else{//存在基础模板ID取模板数据
                    if(nodeTypeAttr != null && objectNodeType.equals(nodeTypeAttr.getValue())
                        && idAttr !=null
                        && info.getQrdxdm().equals(idAttr.getValue())){
                         builder.append(resolveObjectNode(element,info));
                    }
               }


          }
          return builder.toString();
     }

     /**
      * 解析元数据节点
      * @param objElement
      * @return
      */
     private static String resolveObjectNode(Element objElement,TemplateInfo info) {
          StringBuilder builder = new StringBuilder();
          List<Element> objectChildList = objElement.elements(nodeTagName);
          for (Element element : objectChildList) {
               //获取节点类型属性
               Attribute nodeTypeAttr = element.attribute(nodetypeAttrName);
               //获取节点ID属性
               Attribute idAttr = element.attribute(idAttrName);
               if(info.getYzjddm() == null){
                    if(nodeTypeAttr != null && textNodeType.equals(nodeTypeAttr.getValue())){
                         builder.append(element.attribute(textAttrName) == null ? "" :element.attribute(textAttrName).getValue());
                    }else if(nodeTypeAttr != null && atomNodeType.equals(nodeTypeAttr.getValue())){
                         builder.append(resolveAtomNode(element));
                    }
               }else{
                    if(nodeTypeAttr != null && atomNodeType.equals(nodeTypeAttr.getValue())
                            && idAttr !=null
                            && info.getYzjddm().equals(idAttr.getValue())){
                         builder.append(resolveAtomNode(element));
                    }
               }

          }
          return builder.toString();
     }
     /**
      * 解析获取原子节点数据
      * @param node
      * @return
      */
     public static String resolveAtomNode(Element node){
          return node.attribute(valueAttrName).getValue();
     }

     /**
      * 解析获取原子节点数据字典码值
      * @param node
      * @return
      */
     public static String resolveAtomNodeCode(Element node){
          return node.attribute(valueAttrName).getValue().split("`")[0];
     }
     /**
      * 解析获取原子节点数据字典值
      * @param node
      * @return
      */
     public static String resolveAtomNodeValue(Element node){
          return node.attribute(valueAttrName).getValue().split("`")[1];
     }

     /**
      *
      * @param element xml根元素
      * @param dtjddm 动态节点代码  文件结构ID
      * @param qrmbdm 嵌入模板代码  基础模板ID
      * @param qrdxdm 嵌入对象代码  元数据ID
      * @param yzjddm 原子节点代码  原子节点ID
      * @return
      */
     public static String getAttrValue(Element element,String dtjddm,String qrmbdm,String qrdxdm,String yzjddm){
          StringBuilder stringBuilder = new StringBuilder();
          //根据id获取<node nodetype=${DynamicMoleNode} id=${dtjddm}节点元素
          Element dtjdElement = getDtjdElement(element,dtjddm,dtjdNodeType);
          //获取子节点
          List<Element>  childNodeList = dtjdElement.elements(nodeTagName);
          System.out.println(childNodeList.size());
          //遍历子节点
          for (Element childEle : childNodeList) {
               String elementType = childEle.attribute(nodetypeAttrName).getValue();
               System.out.println(elementType);
               //判断是否为文本节点
               if(textNodeType.equals(elementType)){ //文本节点
                    stringBuilder.append(getDtjdChildTextNodeValue(childEle));
               }else{ //依赖节点
                    String refid = childEle.attribute(refidAttrName).getValue();
                    stringBuilder.append(getDtjdChildRefNodeValue(element,refid,qrmbdm,qrdxdm,yzjddm));
               }
          }
          return stringBuilder.toString();
     }

     /**
      * 根据node的refid获取Ref标签
      * @param root
      * @param refid
      * @param qrmbdm
      * @param qrdxdm
      * @param yzjddm
      * @return
      */
     public static String getDtjdChildRefNodeValue(Element root,String refid,String qrmbdm,String qrdxdm,String yzjddm){
          StringBuilder stringBuilder = new StringBuilder();
          //获取子元素
          List<Element> childElements = root.elements(refTagName);
          //获取基础模板元素
          Element qrmbElement = null;
          for (Element element : childElements) {
               if(element.attribute("id").getValue().equals(refid)){
                    //获取子元素下第一个元素 即基础模板
                    Element firstElement = element.element(nodeTagName);
                    String nodetype = firstElement.attribute(nodetypeAttrName).getValue();
                    String elementId = firstElement.attribute("id").getValue();
                    if(refNodeType.equals(nodetype) && qrmbdm.equals(elementId)){
                         qrmbElement = firstElement;
                         break;
                    }
               }
          }
          System.out.println(qrmbElement.attribute(nodetypeAttrName).getValue());
          System.out.println(qrmbElement.attribute("id").getValue());

          List<Element> qrmbChildList =  qrmbElement.elements(nodeTagName);

          for (Element element : qrmbChildList) {
               if(element.attribute("id").getValue().equals(qrdxdm)){

               }
          }
          //获取
          System.out.println(qrmbElement);
          return stringBuilder.toString();
     }


     /**
      * 动态节点下文本节点的值获取
      * @param element
      * @return
      */
     public static String getDtjdChildTextNodeValue(Element element){
          return element.attribute(textAttrName).getValue();
     }
     /**
      * 解析动态节点元素
      * @param root 根元素
      * @param elementId 节点ID
      * @param elementType 节点类型
      * @return
      */
     public static Element getDtjdElement(Element root,String elementId,String elementType){
          Element selElement = null;
          int size = root.nodeCount();
          for (int i = 0;  i < size; i++) {
               Node node = root.node(i);
               if (node instanceof Element) {
                    Element element = (Element) node;
                    String id = element.attribute("id") == null ? null : element.attribute("id").getValue();
                    String nodeType = element.attribute("nodetype") == null ? null : element.attribute("nodetype").getValue();
                    if (id != null && elementId.equals(id) && nodeType != null && elementType.equals(nodeType)) {
                         selElement =  element;
                    }
               }
          }
          return  selElement;
     }

     public static Element getElementById(Element param, String elementID) {
          int i = 0;
          for (int size = param.nodeCount(); i < size; ++i) {
               Node node = param.node(i);
               if (node instanceof Element) {
                    Element element = (Element) node;
                    String id = element.attribute("id") == null ? null : element.attribute("id").getValue();
                    if (id != null && elementID.equals(id)) {
                         return element;
                    }
                    element = getElementById(element, elementID);
                    if (element != null) {
                         return element;
                    }
               }
          }
          return null;
     }
}
